This page has been superceded by a wiki version of this example: CreateLinkUsingCom
/*
IShellLink Example for D
File: createLink.d
Author: Justin C Calvarese
Website: http://jcc_7.tripod.com/d/
License: Public Domain
- Ported to DMD D version 0.59 from BCX/LCC-Win32 by J C Calvarese
- Based on "BCX COM EXAMPLE" (by dl_programmer)
- BCX source in makelink.zip at http://groups.yahoo.com/group/BCX/files/Source_Code/
- Creates a Windows shortcut to an executable, adding several properties.
Compile like this...
dmd createLink ole32.lib uuid.lib
Link with:
ole32.lib
---------
_CoUninitialize@0
_CoInitialize@4
_CoCreateInstance@20
uuid.lib
--------
_CLSID_ShellLink
*/
import std.c.windows.windows;
import std.string;
import std.c.windows.com;
/* Windows API constants */
const int SW_SHOW =5;
const int CP_ACP = 0; // default to ANSI code page
extern(C) const GUID CLSID_ShellLink = {0x00021401, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};
extern(C) const IID IID_IShellLinkA = {0x000214EE, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};
extern(C) const IID IID_IPersistFile = {0x0000010B, 0x0000, 0x0000, [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};
alias IID_IShellLinkA IID_IShellLink;
/* Windows API types */
alias ushort *LPWSTR;
struct SHITEMID {
USHORT cb;
BYTE abID[1];
}
alias SHITEMID* LPSHITEMID;
struct ITEMIDLIST {
SHITEMID mkid;
}
alias ITEMIDLIST* LPCITEMIDLIST;
alias ITEMIDLIST* LPITEMIDLIST;
struct WIN32_FIND_DATA
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
char cFileName[MAX_PATH];
char cAlternateFileName[14];
WORD dummy;
}
alias WIN32_FIND_DATA* LPWIN32_FIND_DATA, PWIN32_FIND_DATA;
struct WIN32_FIND_DATAA
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
CHAR cFileName[MAX_PATH];
CHAR cAlternateFileName[14];
WORD dummy;
}
alias WIN32_FIND_DATAA* LPWIN32_FIND_DATAA, PWIN32_FIND_DATAA;
struct WIN32_FIND_DATAW
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
WCHAR cFileName[MAX_PATH];
WCHAR cAlternateFileName[14];
WORD dummy;
}
alias WIN32_FIND_DATAW* LPWIN32_FIND_DATAW, PWIN32_FIND_DATAW;
/* Windows API functions */
extern(Windows) int MultiByteToWideChar(UINT, DWORD, LPCSTR, int, LPWSTR, int);
alias MessageBoxA MessageBox;
/* objidl.h excerpt */
extern(C) /+const+/ extern IID /+IID_IPersistFile+/ IID_IPERSISTFILE;
extern(Windows) interface IPersistFile: IUnknown
{
/+ HRESULT (_stdcall *QueryInterface)(IPersistFile*,REFIID,void **);
ULONG (_stdcall *AddRef)(IPersistFile*);
ULONG (_stdcall *Release)(IPersistFile*);+/
HRESULT GetClassID(CLSID*);
HRESULT IsDirty();
HRESULT Load(LPCOLESTR, DWORD);
HRESULT Save(LPCOLESTR, BOOL);
HRESULT SaveCompleted(LPCOLESTR);
HRESULT GetCurFile(LPOLESTR*);
}
/* end of objidl.h excerpt */
/* shobjidl.h excerpt */
extern(Windows) interface IPersistIDList: IUnknown
{
/+ HRESULT QueryInterface(REFIID, void **);
ULONG AddRef();
ULONG Release();+/
HRESULT GetClassID(CLSID*);
HRESULT SetIDList(LPCITEMIDLIST);
HRESULT GetIDList(LPITEMIDLIST*);
}
extern(Windows) interface IShellLink: IUnknown
{
/+ HRESULT QueryInterface(REFIID, void **);
ULONG AddRef();
ULONG Release();+/
HRESULT GetPath(LPSTR, int, WIN32_FIND_DATAA*, DWORD);
HRESULT GetIDList(LPITEMIDLIST*);
HRESULT SetIDList(LPCITEMIDLIST);
HRESULT GetDescription(LPSTR, int);
HRESULT SetDescription(LPCSTR);
HRESULT GetWorkingDirectory(LPSTR, int);
HRESULT SetWorkingDirectory(LPCSTR);
HRESULT GetArguments(LPSTR, int);
HRESULT SetArguments(LPCSTR);
HRESULT GetHotkey(WORD*);
HRESULT SetHotkey(WORD);
HRESULT GetShowCmd(int*);
HRESULT SetShowCmd(int);
HRESULT GetIconLocation(LPSTR, int, int*);
HRESULT SetIconLocation(LPCSTR, int);
HRESULT SetRelativePath(LPCSTR, DWORD);
HRESULT Resolve(HWND, DWORD);
HRESULT SetPath(LPCSTR);
}
/* end of shobjidl.h excerpt */
void main()
{
/* You'll probably need to change some paths to reflect your system. */
char[] SCPath = "c:\\windows\\";
char[] szFile;
char[] szTarget;
char[] szDesc;
char[] szIcon;
szFile = SCPath ~ "explorer.exe";
szTarget = SCPath ~ "d_shortcut.lnk";
szIcon = "c:\\dmd\\src\\jcc_7\\examples\\various\\fldr_a.ico";
szDesc = "Shortcut to test.lnk using D!";
if (CreateLink(szFile, szTarget, szDesc, szIcon) == S_OK)
MessageBox(null, "Your shortcut has been created!", "Look at that, D does do COM!", 0);
else
MessageBox(null, "An error occured while trying to create your shortcut", "Aw man...", 0);
}
/* Helpful functions */
char[] Left(char[] s, int leng)
{
/* Left$(s$, leng) */
if (leng <= s.length) return s[0..leng];
return s[];
}
char[] AppPath(char[] path)
{
/* --------------------------------------------------------------------------
DESCRIPTION: Gets a path from full path name
INPUT: String to full path name
OUTPUT: String to path name
USAGE: buffer$ = AppPath$("c:\your directory\your file.exe")
RETURNS: c:\your directory\
-------------------------------------------------------------------------- */
return Left(path, find(path, cast(char[]) "\\"));
}
HRESULT CreateLink(char[] lpszPathObj, char[] lpszPathLink, char[] lpszDesc, char[] lpszIcon)
{
/* --------------------------------------------------------------------------
DESCRIPTION: Creates a Windows shortcut
INPUT: string to EXE, string to shortcut, string to description,
string to icon
OUTPUT: HRESULT to success or failure
USAGE: result = CreateLink("c:\in.exe", "c:\out.lnk, "description")
RETURNS: S_OK if the interface is supported, E_NOINTERFACE if not.
-------------------------------------------------------------------------- */
HRESULT hres;
IShellLink psl;
CoInitialize(null); /* Initialize the COM object */
/* Get a pointer to the IShellLink interface. */
hres = CoCreateInstance(&CLSID_ShellLink, null, CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl);
if (SUCCEEDED(hres))
{
IPersistFile ppf;
/* Sets shortcut location */
psl.SetPath(cast(char*) (lpszPathObj ~ \0));
/* Sets shortcut description */
psl.SetDescription(cast(char*) (lpszDesc ~ \0));
/* Gives shortcut an icon */
psl.SetIconLocation(cast(char*) (lpszIcon ~ \0), 0);
/* Make it full screen */
psl.SetShowCmd(SW_SHOW); /* MAXIMIZED */
/* Set default path */
psl.SetWorkingDirectory(cast(char*) (AppPath(lpszPathObj) ~ \0));
/+ /* Set arguments */
psl.SetArguments("-arg1 -arg2 -arg3"); /*UNCOMMENT THIS IF YOU WANT TO SET ARGUMENTS*/
/* **** Other properties are available! ****
Do not uncomment unless you define the other parameters.
Read the Microsoft PSDK for more info. */
psl.SetHotkey(wHotkey);
psl.SetIDList(pidl);
psl.SetRelativePath(pszPathRel, null); +/
/* Query IShellLink for the IPersistFile interface for saving the
shortcut in persistent storage. */
hres = psl.QueryInterface(&IID_IPersistFile, cast(void **) &ppf);
if (SUCCEEDED(hres))
{
WORD wsz[MAX_PATH];
/* Ensure that the string is ANSI. */
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
/* Save the link by calling IPersistFile::Save. */
hres = ppf.Save(cast(wchar*) wsz, cast(int) true);
ppf.Release();
}
psl.Release();
}
CoUninitialize(); /* Uninitialize the COM object */
return hres;
}